package com.mobileClientKernel.android.serviceManager.servicefactory;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;

import com.mobileClientKernel.android.serviceManager.help.ReflectUtil;
import com.mobileClientKernel.android.serviceManager.service.JJService;

import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * Created by hamilyjing on 3/31/16.
 */
public class JJServiceFactory {

    private Context context;

    private static JJServiceFactory instance = new JJServiceFactory();

    private HashMap<String, JJService> serviceHashMap = new HashMap<>();

    private Lock lock = new ReentrantLock(); // 定义锁对象

    private Date beginDateOfUnloadingService = new Date();
    private long checkIntervalOfUnloadingService = 600000 * 1000; // 600000 second

    private List<String> loginSuccessNotificationActionArray;
    private List<String> logoutNotificationActionArray;

    private MyReceiver myReceiver = new MyReceiver();

    public static JJServiceFactory getInstance() {
        return instance;
    }

    private JJServiceFactory() {
    }

    public JJService getService(String serviceName) {
        lock.lock();

        JJService service;

        do {
            service = serviceHashMap.get(serviceName);
            if (service != null) {
                break;
            }

            long timeInterval = (new Date()).getTime() - beginDateOfUnloadingService.getTime();
            boolean isNeedUnload = timeInterval > checkIntervalOfUnloadingService;
            if (isNeedUnload) {
                unloadUnneededServiceWithNoLock();
                beginDateOfUnloadingService = new Date();
            }

            service = ReflectUtil.newInstance(serviceName);
            if (null == service) {
                service = ReflectUtil.getInstance(serviceName);
            }

            if (null == service) {
                break;
            }

            service.serviceWillLoad();
            serviceHashMap.put(serviceName, service);
            service.serviceDidLoad();

        } while (true);

        lock.unlock();

        return service;
    }

    public void unloadService(String serviceName, boolean isForceUnload) {
        lock.lock();

        do {
            JJService service = serviceHashMap.get(serviceName);
            if (null == service) {
                break;
            }

            if (!isForceUnload && !service.needUnloading()) {
                break;
            }

            service.serviceWillUnload();
            serviceHashMap.remove(serviceName);
            service.serviceDidUnload();

        } while (true);

        lock.unlock();
    }

    public void unloadService(String serviceName) {
        unloadService(serviceName, false);
    }

    private void unloadUnneededServiceWithNoLock() {
        Iterator iterator = serviceHashMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            JJService service = (JJService) entry.getValue();

            if (service.needUnloading()) {
                iterator.remove();
            }
        }
    }

    public void actionAfterLogin(Intent intent) {
        lock.lock();

        Iterator iterator = serviceHashMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            JJService service = (JJService) entry.getValue();
            service.actionAfterLogin(intent);
        }

        lock.unlock();
    }

    public void actionAfterLogout(Intent intent) {
        lock.lock();

        Iterator iterator = serviceHashMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Map.Entry entry = (Map.Entry) iterator.next();
            JJService service = (JJService) entry.getValue();
            service.actionAfterLogout(intent);
        }

        lock.unlock();
    }

    public long getCheckIntervalOfUnloadingService() {
        return checkIntervalOfUnloadingService;
    }

    public void setCheckIntervalOfUnloadingService(long checkIntervalOfUnloadingService) {
        this.checkIntervalOfUnloadingService = checkIntervalOfUnloadingService;
    }

    public List<String> getLoginSuccessNotificationActionArray() {
        return loginSuccessNotificationActionArray;
    }

    public void setLoginSuccessNotificationActionArray(List<String> loginSuccessNotificationActionArray) {
        this.loginSuccessNotificationActionArray = loginSuccessNotificationActionArray;
    }

    public List<String> getLogoutNotificationActionArray() {
        return logoutNotificationActionArray;
    }

    public void setLogoutNotificationActionArray(List<String> logoutNotificationActionArray) {
        this.logoutNotificationActionArray = logoutNotificationActionArray;
    }

    public Context getContext() {
        return context;
    }

    public void setContext(Context context) {
        if (this.context != null) {
            context.unregisterReceiver(myReceiver);
        }

        this.context = context;
        IntentFilter filter = new IntentFilter();
        context.registerReceiver(myReceiver, filter);
    }

    class MyReceiver extends BroadcastReceiver {

        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (getLoginSuccessNotificationActionArray().contains(action)) {
                actionAfterLogin(intent);
            } else if (getLogoutNotificationActionArray().contains(action)) {
                actionAfterLogout(intent);
            }
        }
    }
}
